!-------------------------------------------------------------LICENSE--------------------------------------------------------------!
!                                                                                                                                  !
!The MAP code is written in Fortran language for magnetohydrodynamics (MHD) calculation with the adaptive mesh refinement (AMR)    !
!and Message Passing Interface (MPI) parallelization.                                                                              !
!                                                                                                                                  !
!Copyright (C) 2012                                                                                                                !
!Ronglin Jiang                                                                                                                     !
!rljiang@ssc.net.cn                                                                                                                !
!585 Guoshoujing Road. Pudong, Shanghai, P.R.C. 201203                                                                             !
!                                                                                                                                  !
!This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License         !
!as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.             !
!                                                                                                                                  !
!This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of    !
!MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.                        !
!                                                                                                                                  !
!You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software     !
!Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.                                                   !
!                                                                                                                                  !
!-------------------------------------------------------------LICENSE--------------------------------------------------------------!

!==================================================================================================================================|
subroutine neigh_statistics (base)
!==================================================================================================================================|

   use parameters
   use block_define
   implicit none

   type(block), pointer, intent(in) :: base

   integer(4) :: i_neigh, j_neigh, k_neigh, i_cpu, i_block, j_block, k_block !, i_neigh_x, i_neigh_y
   integer(4) :: child_cpu_id_p1, neigh_cpu_id_p1, neigh_index !, n_tmp, tmp_flag
   integer(4), dimension(cpu_number) :: n_neighs_exchange_send_x, n_neighs_exchange_send_y, n_neighs_exchange_send_z
   integer(4), dimension(cpu_number) :: n_neighs_reflux_send_x, n_neighs_reflux_send_y, n_neighs_reflux_send_z
   integer(4), dimension(cpu_number) :: n_neighs_shareblock_send_x, n_neighs_shareblock_send_y, n_neighs_shareblock_send_z
   integer(4), dimension(cpu_number) :: n_neighs_exchange_send_fix_y, n_neighs_exchange_send_fix_z

   integer(4) :: reflux_size_x_tmp
   integer(4) :: reflux_size_y_tmp
   integer(4) :: reflux_size_z_tmp
   integer(4) :: shareblock_size_x_tmp
   integer(4) :: shareblock_size_y_tmp
   integer(4) :: shareblock_size_z_tmp
   integer(4) :: exchange_size_x_tmp
   integer(4) :: exchange_size_y_tmp
   integer(4) :: exchange_size_z_tmp

   integer(4), dimension(:, :, :), allocatable :: neighs_reflux_info_send_x_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_reflux_info_send_y_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_reflux_info_send_z_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_reflux_info_recv_x_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_reflux_info_recv_y_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_reflux_info_recv_z_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_shareblock_info_send_x_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_shareblock_info_send_y_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_shareblock_info_send_z_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_shareblock_info_recv_x_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_shareblock_info_recv_y_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_shareblock_info_recv_z_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_exchange_info_send_x_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_exchange_info_send_y_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_exchange_info_send_z_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_exchange_info_recv_x_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_exchange_info_recv_y_tmp
   integer(4), dimension(:, :, :), allocatable :: neighs_exchange_info_recv_z_tmp

   logical(4) :: child_send_flag(cpu_number) !, neigh_flag(cpu_number)
   type(block), pointer :: current, neigh, child !, neigh_x

!----------------------------------------------------------------------------------------------------------------------------------|
   do i_cpu = 1, cpu_number
      n_neighs_exchange_send_x(i_cpu) = 0
      n_neighs_exchange_send_y(i_cpu) = 0
      n_neighs_exchange_send_z(i_cpu) = 0
      n_neighs_reflux_send_x(i_cpu) = 0
      n_neighs_reflux_send_y(i_cpu) = 0
      n_neighs_reflux_send_z(i_cpu) = 0
      n_neighs_shareblock_send_x(i_cpu) = 0
      n_neighs_shareblock_send_y(i_cpu) = 0
      n_neighs_shareblock_send_z(i_cpu) = 0
      n_neighs_exchange_send_fix_y(i_cpu) = 0
      n_neighs_exchange_send_fix_z(i_cpu) = 0
   enddo

!----------------------------------------------------------------------------------------------------------------------------------|
!  update cpu_number_neigh
!----------------------------------------------------------------------------------------------------------------------------------|
!   neigh_flag = .false.
!   cpu_number_neigh_tmp = 0

   if (allocated(neighs_reflux_send_x)) deallocate(neighs_reflux_send_x)
   if (allocated(neighs_reflux_send_y)) deallocate(neighs_reflux_send_y)
   if (allocated(neighs_reflux_send_z)) deallocate(neighs_reflux_send_z)
   if (allocated(neighs_reflux_recv_x)) deallocate(neighs_reflux_recv_x)
   if (allocated(neighs_reflux_recv_y)) deallocate(neighs_reflux_recv_y)
   if (allocated(neighs_reflux_recv_z)) deallocate(neighs_reflux_recv_z)

   if (allocated(neighs_shareblock_send_x)) deallocate(neighs_shareblock_send_x)
   if (allocated(neighs_shareblock_send_y)) deallocate(neighs_shareblock_send_y)
   if (allocated(neighs_shareblock_send_z)) deallocate(neighs_shareblock_send_z)
   if (allocated(neighs_shareblock_recv_x)) deallocate(neighs_shareblock_recv_x)
   if (allocated(neighs_shareblock_recv_y)) deallocate(neighs_shareblock_recv_y)
   if (allocated(neighs_shareblock_recv_z)) deallocate(neighs_shareblock_recv_z)

   if (allocated(neighs_exchange_send_x)) deallocate(neighs_exchange_send_x)
   if (allocated(neighs_exchange_send_y)) deallocate(neighs_exchange_send_y)
   if (allocated(neighs_exchange_send_z)) deallocate(neighs_exchange_send_z)
   if (allocated(neighs_exchange_recv_x)) deallocate(neighs_exchange_recv_x)
   if (allocated(neighs_exchange_recv_y)) deallocate(neighs_exchange_recv_y)
   if (allocated(neighs_exchange_recv_z)) deallocate(neighs_exchange_recv_z)

!      allocate(neighs_reflux_send_x(sys, ny_no_bnd, nz_no_bnd, reflux_size_x, cpu_number_neigh))
!      allocate(neighs_reflux_send_y(sys, nx_no_bnd, nz_no_bnd, reflux_size_y, cpu_number_neigh))
!      allocate(neighs_reflux_send_z(sys, nx_no_bnd, ny_no_bnd, reflux_size_z, cpu_number_neigh))
!      allocate(neighs_reflux_recv_x(sys, ny_no_bnd, nz_no_bnd, reflux_size_x, cpu_number_neigh))
!      allocate(neighs_reflux_recv_y(sys, nx_no_bnd, nz_no_bnd, reflux_size_y, cpu_number_neigh))
!      allocate(neighs_reflux_recv_z(sys, nx_no_bnd, ny_no_bnd, reflux_size_z, cpu_number_neigh))

!      allocate(neighs_shareblock_send_x(sysp1, ng + 1, ny_block, nz_block, shareblock_size_x, cpu_number_neigh))
!      allocate(neighs_shareblock_send_y(sysp1, nx_block, ng + 1, nz_block, shareblock_size_y, cpu_number_neigh))
!      allocate(neighs_shareblock_send_z(sysp1, nx_block, ny_block, ng + 1, shareblock_size_z, cpu_number_neigh))
!      allocate(neighs_shareblock_recv_x(sysp1, ng + 1, ny_block, nz_block, shareblock_size_x, cpu_number_neigh))
!      allocate(neighs_shareblock_recv_y(sysp1, nx_block, ng + 1, nz_block, shareblock_size_y, cpu_number_neigh))
!      allocate(neighs_shareblock_recv_z(sysp1, nx_block, ny_block, ng + 1, shareblock_size_z, cpu_number_neigh))

!      allocate(neighs_exchange_send_x(sysp1, ng, ny_no_bnd, nz_no_bnd, exchange_size_x, cpu_number_neigh))
!      allocate(neighs_exchange_send_y(sysp1, nx_block, ng, nz_no_bnd, exchange_size_y, cpu_number_neigh))
!      allocate(neighs_exchange_send_z(sysp1, nx_block, ny_block, ng, exchange_size_z, cpu_number_neigh))
!      allocate(neighs_exchange_recv_x(sysp1, ng, ny_no_bnd, nz_no_bnd, exchange_size_x, cpu_number_neigh))
!      allocate(neighs_exchange_recv_y(sysp1, nx_block, ng, nz_no_bnd, exchange_size_y, cpu_number_neigh))
!      allocate(neighs_exchange_recv_z(sysp1, nx_block, ny_block, ng, exchange_size_z, cpu_number_neigh))
!   endif

   current => base%next
   do while (current%lv .ne. 0)
!----------------------------------------------------------------------------------------------------------------------------------|
!     statistics in x direction
!----------------------------------------------------------------------------------------------------------------------------------|
      k_neigh = 0
      j_neigh = 0
      do i_neigh = -1, 1, 2      !  skip current%neigh(0, 0, 0)%pblock
         neigh => current%neigh(i_neigh, j_neigh, k_neigh)%pblock

!----------------------------------------------------------------------------------------------------------------------------------|
!        skip if neigh is physical boundary or inner physical boundary
!----------------------------------------------------------------------------------------------------------------------------------|
         if (.not. associated(neigh)) cycle
         if (neigh%lv .lt. 0) cycle

         neigh_cpu_id_p1 = neigh%cpu_id + 1

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending reflux data in x (different levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (current%lv .gt. neigh%lv .and. neigh%cpu_id .ne. cpu_id) then
            n_neighs_reflux_send_x(neigh_cpu_id_p1) = n_neighs_reflux_send_x(neigh_cpu_id_p1) + 1
            neigh_index = n_neighs_reflux_send_x(neigh_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!           for the case n_neighs_reflux_send_x(neigh_cpu_id_p1) larger than the reflux_size_x
!----------------------------------------------------------------------------------------------------------------------------------|
            if (neigh_index .gt. reflux_size_x) then
               allocate(neighs_reflux_info_send_x_tmp(n_d_l + 1, reflux_size_x, cpu_number))
               allocate(neighs_reflux_info_recv_x_tmp(n_d_l + 1, reflux_size_x, cpu_number))
               reflux_size_x_tmp = reflux_size_x
               neighs_reflux_info_send_x_tmp = neighs_reflux_info_send_x
               neighs_reflux_info_recv_x_tmp = neighs_reflux_info_recv_x
               reflux_size_x = reflux_size_x + ini_block_x * ini_block_y * ini_block_z
               deallocate(neighs_reflux_info_send_x)
               deallocate(neighs_reflux_info_recv_x)
               allocate(neighs_reflux_info_send_x(n_d_l + 1, reflux_size_x, cpu_number))
               allocate(neighs_reflux_info_recv_x(n_d_l + 1, reflux_size_x, cpu_number))
               neighs_reflux_info_send_x(:, 1 : reflux_size_x_tmp, :) = neighs_reflux_info_send_x_tmp
               neighs_reflux_info_recv_x(:, 1 : reflux_size_x_tmp, :) = neighs_reflux_info_recv_x_tmp
               deallocate(neighs_reflux_info_send_x_tmp)
               deallocate(neighs_reflux_info_recv_x_tmp)
            endif
            neighs_reflux_info_send_x(1 : n_d_l, neigh_index, neigh_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
            neighs_reflux_info_send_x(n_d_l + 1, neigh_index, neigh_cpu_id_p1) = i_neigh
            cycle
         endif

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending boundary data in x (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (neigh%lv .eq. current%lv .and. neigh%cpu_id .ne. cpu_id) then
!            neigh%var_deallocate_flag = .false.
!            if (.not. neigh%var_allocate_flag) then
!               allocate(neigh%ro(nx_block, ny_block, nz_block), neigh%mx(nx_block, ny_block, nz_block),                            &
!                        neigh%my(nx_block, ny_block, nz_block), neigh%mz(nx_block, ny_block, nz_block),                            &
!                        neigh%bx(nx_block, ny_block, nz_block), neigh%by(nx_block, ny_block, nz_block),                            &
!                        neigh%bz(nx_block, ny_block, nz_block), neigh%en(nx_block, ny_block, nz_block),                            &
!                        neigh%gx(nx_block, ny_block, nz_block), neigh%gy(nx_block, ny_block, nz_block),                            &
!                        neigh%gz(nx_block, ny_block, nz_block), neigh%po(nx_block, ny_block, nz_block))
!               allocate(neigh%fxro_bnd(ny_block, nz_block, n_neighs), neigh%fxmx_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxmy_bnd(ny_block, nz_block, n_neighs), neigh%fxmz_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxbx_bnd(ny_block, nz_block, n_neighs), neigh%fxby_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxbz_bnd(ny_block, nz_block, n_neighs), neigh%fxen_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxpo_bnd(ny_block, nz_block, n_neighs),                                                              &
!                        neigh%fyro_bnd(nx_block, nz_block, n_neighs), neigh%fymx_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fymy_bnd(nx_block, nz_block, n_neighs), neigh%fymz_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fybx_bnd(nx_block, nz_block, n_neighs), neigh%fyby_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fybz_bnd(nx_block, nz_block, n_neighs), neigh%fyen_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fypo_bnd(nx_block, nz_block, n_neighs),                                                              &
!                        neigh%fzro_bnd(nx_block, ny_block, n_neighs), neigh%fzmx_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzmy_bnd(nx_block, ny_block, n_neighs), neigh%fzmz_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzbx_bnd(nx_block, ny_block, n_neighs), neigh%fzby_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzbz_bnd(nx_block, ny_block, n_neighs), neigh%fzen_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzpo_bnd(nx_block, ny_block, n_neighs))
!               neigh%var_allocate_flag = .true.
!               if (ini_value_save_flag .ne. 0) then
!                  allocate(neigh%ro0(nx_block, ny_block, nz_block), neigh%mx0(nx_block, ny_block, nz_block),                       &
!                           neigh%my0(nx_block, ny_block, nz_block), neigh%mz0(nx_block, ny_block, nz_block),                       &
!                           neigh%bx0(nx_block, ny_block, nz_block), neigh%by0(nx_block, ny_block, nz_block),                       &
!                           neigh%bz0(nx_block, ny_block, nz_block), neigh%en0(nx_block, ny_block, nz_block))
!               endif
!            endif
            n_neighs_exchange_send_x(neigh_cpu_id_p1) = n_neighs_exchange_send_x(neigh_cpu_id_p1) + 1
            neigh_index = n_neighs_exchange_send_x(neigh_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!           for the case n_neighs_exchange_send_x(neigh_cpu_id_p1) larger than the exchange_size_x
!----------------------------------------------------------------------------------------------------------------------------------|
            if (neigh_index .gt. exchange_size_x) then
               allocate(neighs_exchange_info_send_x_tmp(n_d_l + 1, exchange_size_x, cpu_number))
               allocate(neighs_exchange_info_recv_x_tmp(n_d_l + 1, exchange_size_x, cpu_number))
               exchange_size_x_tmp = exchange_size_x
               neighs_exchange_info_send_x_tmp = neighs_exchange_info_send_x
               neighs_exchange_info_recv_x_tmp = neighs_exchange_info_recv_x
               exchange_size_x = exchange_size_x + ini_block_x * ini_block_y * ini_block_z
               deallocate(neighs_exchange_info_send_x)
               deallocate(neighs_exchange_info_recv_x)
               allocate(neighs_exchange_info_send_x(n_d_l + 1, exchange_size_x, cpu_number))
               allocate(neighs_exchange_info_recv_x(n_d_l + 1, exchange_size_x, cpu_number))
               neighs_exchange_info_send_x(:, 1 : exchange_size_x_tmp, :) = neighs_exchange_info_send_x_tmp
               neighs_exchange_info_recv_x(:, 1 : exchange_size_x_tmp, :) = neighs_exchange_info_recv_x_tmp
               deallocate(neighs_exchange_info_send_x_tmp)
               deallocate(neighs_exchange_info_recv_x_tmp)
            endif
            neighs_exchange_info_send_x(1 : n_d_l, neigh_index, neigh_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
            neighs_exchange_info_send_x(n_d_l + 1, neigh_index, neigh_cpu_id_p1) = i_neigh
         endif

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending sharing block data in x (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (neigh%lv .eq. current%lv .and. current%nc .ne. 0 .and. neigh%nc .eq. 0) then
            child_send_flag = .false.
            if (i_neigh .eq. -1) i_block = 1
            if (i_neigh .eq. 1) i_block = ratio
            do k_block = 1, ratio
            do j_block = 1, ratio
               child => current%child(i_block, j_block, k_block)%pblock
               child_cpu_id_p1 = child%cpu_id + 1
               if (child%cpu_id .ne. current%cpu_id .and. .not. child_send_flag(child_cpu_id_p1)) then
                  n_neighs_shareblock_send_x(child_cpu_id_p1) = n_neighs_shareblock_send_x(child_cpu_id_p1) + 1
                  neigh_index = n_neighs_shareblock_send_x(child_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!                 for the case n_neighs_shareblock_send_x(neigh_cpu_id_p1) larger than the shareblock_size_x
!----------------------------------------------------------------------------------------------------------------------------------|
                  if (neigh_index .gt. shareblock_size_x) then
                     allocate(neighs_shareblock_info_send_x_tmp(n_d_l + 1, shareblock_size_x, cpu_number))
                     allocate(neighs_shareblock_info_recv_x_tmp(n_d_l + 1, shareblock_size_x, cpu_number))
                     shareblock_size_x_tmp = shareblock_size_x
                     neighs_shareblock_info_send_x_tmp = neighs_shareblock_info_send_x
                     neighs_shareblock_info_recv_x_tmp = neighs_shareblock_info_recv_x
                     shareblock_size_x = shareblock_size_x + ini_block_x * ini_block_y * ini_block_z
                     deallocate(neighs_shareblock_info_send_x)
                     deallocate(neighs_shareblock_info_recv_x)
                     allocate(neighs_shareblock_info_send_x(n_d_l + 1, shareblock_size_x, cpu_number))
                     allocate(neighs_shareblock_info_recv_x(n_d_l + 1, shareblock_size_x, cpu_number))
                     neighs_shareblock_info_send_x(:, 1 : shareblock_size_x_tmp, :) = neighs_shareblock_info_send_x_tmp
                     neighs_shareblock_info_recv_x(:, 1 : shareblock_size_x_tmp, :) = neighs_shareblock_info_recv_x_tmp
                     deallocate(neighs_shareblock_info_send_x_tmp)
                     deallocate(neighs_shareblock_info_recv_x_tmp)
                  endif
                  neighs_shareblock_info_send_x(1 : n_d_l, neigh_index, child_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
                  neighs_shareblock_info_send_x(n_d_l + 1, neigh_index, child_cpu_id_p1) = i_neigh
                  child_send_flag(child_cpu_id_p1) = .true.
               endif
            enddo
            enddo
         endif
      enddo

!----------------------------------------------------------------------------------------------------------------------------------|
!     statistics in y direction
!----------------------------------------------------------------------------------------------------------------------------------|
      k_neigh = 0
      i_neigh = 0
      do j_neigh = -1, 1, 2      !  skip current%neigh(0, 0, 0)%pblock
         neigh => current%neigh(i_neigh, j_neigh, k_neigh)%pblock

!----------------------------------------------------------------------------------------------------------------------------------|
!        skip if neigh is physical boundary or inner physical boundary
!----------------------------------------------------------------------------------------------------------------------------------|
         if (.not. associated (neigh)) cycle
         if (neigh%lv .lt. 0) cycle

         neigh_cpu_id_p1 = neigh%cpu_id + 1

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending reflux data in y (different levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (current%lv .gt. neigh%lv .and. neigh%cpu_id .ne. cpu_id) then
            n_neighs_reflux_send_y(neigh_cpu_id_p1) = n_neighs_reflux_send_y(neigh_cpu_id_p1) + 1
            neigh_index = n_neighs_reflux_send_y(neigh_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!           for the case n_neighs_reflux_send_y(neigh_cpu_id_p1) larger than the reflux_size_y
!----------------------------------------------------------------------------------------------------------------------------------|
            if (neigh_index .gt. reflux_size_y) then
               allocate(neighs_reflux_info_send_y_tmp(n_d_l + 1, reflux_size_y, cpu_number))
               allocate(neighs_reflux_info_recv_y_tmp(n_d_l + 1, reflux_size_y, cpu_number))
               reflux_size_y_tmp = reflux_size_y
               neighs_reflux_info_send_y_tmp = neighs_reflux_info_send_y
               neighs_reflux_info_recv_y_tmp = neighs_reflux_info_recv_y
               reflux_size_y = reflux_size_y + ini_block_x * ini_block_y * ini_block_z
               deallocate(neighs_reflux_info_send_y)
               deallocate(neighs_reflux_info_recv_y)
               allocate(neighs_reflux_info_send_y(n_d_l + 1, reflux_size_y, cpu_number))
               allocate(neighs_reflux_info_recv_y(n_d_l + 1, reflux_size_y, cpu_number))
               neighs_reflux_info_send_y(:, 1 : reflux_size_y_tmp, :) = neighs_reflux_info_send_y_tmp
               neighs_reflux_info_recv_y(:, 1 : reflux_size_y_tmp, :) = neighs_reflux_info_recv_y_tmp
               deallocate(neighs_reflux_info_send_y_tmp)
               deallocate(neighs_reflux_info_recv_y_tmp)
            endif
            neighs_reflux_info_send_y(1 : n_d_l, neigh_index, neigh_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
            neighs_reflux_info_send_y(n_d_l + 1, neigh_index, neigh_cpu_id_p1) = j_neigh
            cycle
         endif

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending boundary data in y (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (neigh%lv .eq. current%lv .and. neigh%cpu_id .ne. cpu_id) then
!            neigh%var_deallocate_flag = .false.
!            if (.not. neigh%var_allocate_flag) then
!               allocate(neigh%ro(nx_block, ny_block, nz_block), neigh%mx(nx_block, ny_block, nz_block),                            &
!                        neigh%my(nx_block, ny_block, nz_block), neigh%mz(nx_block, ny_block, nz_block),                            &
!                        neigh%bx(nx_block, ny_block, nz_block), neigh%by(nx_block, ny_block, nz_block),                            &
!                        neigh%bz(nx_block, ny_block, nz_block), neigh%en(nx_block, ny_block, nz_block),                            &
!                        neigh%gx(nx_block, ny_block, nz_block), neigh%gy(nx_block, ny_block, nz_block),                            &
!                        neigh%gz(nx_block, ny_block, nz_block), neigh%po(nx_block, ny_block, nz_block))
!               allocate(neigh%fxro_bnd(ny_block, nz_block, n_neighs), neigh%fxmx_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxmy_bnd(ny_block, nz_block, n_neighs), neigh%fxmz_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxbx_bnd(ny_block, nz_block, n_neighs), neigh%fxby_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxbz_bnd(ny_block, nz_block, n_neighs), neigh%fxen_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxpo_bnd(ny_block, nz_block, n_neighs),                                                              &
!                        neigh%fyro_bnd(nx_block, nz_block, n_neighs), neigh%fymx_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fymy_bnd(nx_block, nz_block, n_neighs), neigh%fymz_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fybx_bnd(nx_block, nz_block, n_neighs), neigh%fyby_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fybz_bnd(nx_block, nz_block, n_neighs), neigh%fyen_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fypo_bnd(nx_block, nz_block, n_neighs),                                                              &
!                        neigh%fzro_bnd(nx_block, ny_block, n_neighs), neigh%fzmx_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzmy_bnd(nx_block, ny_block, n_neighs), neigh%fzmz_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzbx_bnd(nx_block, ny_block, n_neighs), neigh%fzby_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzbz_bnd(nx_block, ny_block, n_neighs), neigh%fzen_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzpo_bnd(nx_block, ny_block, n_neighs))
!               neigh%var_allocate_flag = .true.
!               if (ini_value_save_flag .ne. 0) then
!                  allocate(neigh%ro0(nx_block, ny_block, nz_block), neigh%mx0(nx_block, ny_block, nz_block),                       &
!                           neigh%my0(nx_block, ny_block, nz_block), neigh%mz0(nx_block, ny_block, nz_block),                       &
!                           neigh%bx0(nx_block, ny_block, nz_block), neigh%by0(nx_block, ny_block, nz_block),                       &
!                           neigh%bz0(nx_block, ny_block, nz_block), neigh%en0(nx_block, ny_block, nz_block))
!               endif
!            endif
            n_neighs_exchange_send_y(neigh_cpu_id_p1) = n_neighs_exchange_send_y(neigh_cpu_id_p1) + 1
            neigh_index = n_neighs_exchange_send_y(neigh_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!           for the case n_neighs_exchange_send_y(neigh_cpu_id_p1) larger than the exchange_size_y
!----------------------------------------------------------------------------------------------------------------------------------|
            if (neigh_index .gt. exchange_size_y) then
               allocate(neighs_exchange_info_send_y_tmp(n_d_l + 1, exchange_size_y, cpu_number))
               allocate(neighs_exchange_info_recv_y_tmp(n_d_l + 1, exchange_size_y, cpu_number))
               exchange_size_y_tmp = exchange_size_y
               neighs_exchange_info_send_y_tmp = neighs_exchange_info_send_y
               neighs_exchange_info_recv_y_tmp = neighs_exchange_info_recv_y
               exchange_size_y = exchange_size_y + ini_block_x * ini_block_y * ini_block_z
               deallocate(neighs_exchange_info_send_y)
               deallocate(neighs_exchange_info_recv_y)
               allocate(neighs_exchange_info_send_y(n_d_l + 1, exchange_size_y, cpu_number))
               allocate(neighs_exchange_info_recv_y(n_d_l + 1, exchange_size_y, cpu_number))
               neighs_exchange_info_send_y(:, 1 : exchange_size_y_tmp, :) = neighs_exchange_info_send_y_tmp
               neighs_exchange_info_recv_y(:, 1 : exchange_size_y_tmp, :) = neighs_exchange_info_recv_y_tmp
               deallocate(neighs_exchange_info_send_y_tmp)
               deallocate(neighs_exchange_info_recv_y_tmp)
            endif
            neighs_exchange_info_send_y(1 : n_d_l, neigh_index, neigh_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
            neighs_exchange_info_send_y(n_d_l + 1, neigh_index, neigh_cpu_id_p1) = j_neigh

!----------------------------------------------------------------------------------------------------------------------------------|
!           collect information of neighbors for fixing boundary data in y because of the shareblocks (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
!            do i_neigh_x = -1, 1, 2
!               neigh_x => current%neigh(i_neigh_x, 0)%pblock
!               if (associated (neigh_x)) then
!                  if (neigh_x%lv .eq. current%lv - 1) then
!                     n_neighs_exchange_send_fix_y(neigh_cpu_id_p1) = n_neighs_exchange_send_fix_y(neigh_cpu_id_p1) + 1
!                     exit
!                  endif
!               endif
!            enddo
         endif

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending sharing block data in y (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (neigh%lv .eq. current%lv .and. current%nc .ne. 0 .and. neigh%nc .eq. 0) then
            child_send_flag = .false.
            if (j_neigh .eq. -1) j_block = 1
            if (j_neigh .eq. 1) j_block = ratio
            do k_block = 1, ratio
            do i_block = 1, ratio
               child => current%child(i_block, j_block, k_block)%pblock
               child_cpu_id_p1 = child%cpu_id + 1
               if (child%cpu_id .ne. current%cpu_id .and. .not. child_send_flag(child_cpu_id_p1)) then
                  n_neighs_shareblock_send_y(child_cpu_id_p1) = n_neighs_shareblock_send_y(child_cpu_id_p1) + 1
                  neigh_index = n_neighs_shareblock_send_y(child_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!                 for the case n_neighs_shareblock_send_y(neigh_cpu_id_p1) larger than the shareblock_size_y
!----------------------------------------------------------------------------------------------------------------------------------|
                  if (neigh_index .gt. shareblock_size_y) then
                     allocate(neighs_shareblock_info_send_y_tmp(n_d_l + 1, shareblock_size_y, cpu_number))
                     allocate(neighs_shareblock_info_recv_y_tmp(n_d_l + 1, shareblock_size_y, cpu_number))
                     shareblock_size_y_tmp = shareblock_size_y
                     neighs_shareblock_info_send_y_tmp = neighs_shareblock_info_send_y
                     neighs_shareblock_info_recv_y_tmp = neighs_shareblock_info_recv_y
                     shareblock_size_y = shareblock_size_y + ini_block_x * ini_block_y * ini_block_z
                     deallocate(neighs_shareblock_info_send_y)
                     deallocate(neighs_shareblock_info_recv_y)
                     allocate(neighs_shareblock_info_send_y(n_d_l + 1, shareblock_size_y, cpu_number))
                     allocate(neighs_shareblock_info_recv_y(n_d_l + 1, shareblock_size_y, cpu_number))
                     neighs_shareblock_info_send_y(:, 1 : shareblock_size_y_tmp, :) = neighs_shareblock_info_send_y_tmp
                     neighs_shareblock_info_recv_y(:, 1 : shareblock_size_y_tmp, :) = neighs_shareblock_info_recv_y_tmp
                     deallocate(neighs_shareblock_info_send_y_tmp)
                     deallocate(neighs_shareblock_info_recv_y_tmp)
                  endif
                  neighs_shareblock_info_send_y(1 : n_d_l, neigh_index, child_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
                  neighs_shareblock_info_send_y(n_d_l + 1, neigh_index, child_cpu_id_p1) = j_neigh
                  child_send_flag(child_cpu_id_p1) = .true.
               endif
            enddo
            enddo
         endif
      enddo

!----------------------------------------------------------------------------------------------------------------------------------|
!     statistics in z direction
!----------------------------------------------------------------------------------------------------------------------------------|
      j_neigh = 0
      i_neigh = 0
      do k_neigh = -1, 1, 2      !  skip current%neigh(0, 0, 0)%pblock
         neigh => current%neigh(i_neigh, j_neigh, k_neigh)%pblock

!----------------------------------------------------------------------------------------------------------------------------------|
!        skip if neigh is physical boundary or inner physical boundary
!----------------------------------------------------------------------------------------------------------------------------------|
         if (.not. associated (neigh)) cycle
         if (neigh%lv .lt. 0) cycle

         neigh_cpu_id_p1 = neigh%cpu_id + 1

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending reflux data in z (different levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (current%lv .gt. neigh%lv .and. neigh%cpu_id .ne. cpu_id) then
            n_neighs_reflux_send_z(neigh_cpu_id_p1) = n_neighs_reflux_send_z(neigh_cpu_id_p1) + 1
            neigh_index = n_neighs_reflux_send_z(neigh_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!           for the case n_neighs_reflux_send_z(neigh_cpu_id_p1) larger than the reflux_size_z
!----------------------------------------------------------------------------------------------------------------------------------|
            if (neigh_index .gt. reflux_size_z) then
               allocate(neighs_reflux_info_send_z_tmp(n_d_l + 1, reflux_size_z, cpu_number))
               allocate(neighs_reflux_info_recv_z_tmp(n_d_l + 1, reflux_size_z, cpu_number))
               reflux_size_z_tmp = reflux_size_z
               neighs_reflux_info_send_z_tmp = neighs_reflux_info_send_z
               neighs_reflux_info_recv_z_tmp = neighs_reflux_info_recv_z
               reflux_size_z = reflux_size_z + ini_block_x * ini_block_y * ini_block_z
               deallocate(neighs_reflux_info_send_z)
               deallocate(neighs_reflux_info_recv_z)
               allocate(neighs_reflux_info_send_z(n_d_l + 1, reflux_size_z, cpu_number))
               allocate(neighs_reflux_info_recv_z(n_d_l + 1, reflux_size_z, cpu_number))
               neighs_reflux_info_send_z(:, 1 : reflux_size_z_tmp, :) = neighs_reflux_info_send_z_tmp
               neighs_reflux_info_recv_z(:, 1 : reflux_size_z_tmp, :) = neighs_reflux_info_recv_z_tmp
               deallocate(neighs_reflux_info_send_z_tmp)
               deallocate(neighs_reflux_info_recv_z_tmp)
            endif
            neighs_reflux_info_send_z(1 : n_d_l, neigh_index, neigh_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
            neighs_reflux_info_send_z(n_d_l + 1, neigh_index, neigh_cpu_id_p1) = k_neigh
            cycle
         endif

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending boundary data in z (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (neigh%lv .eq. current%lv .and. neigh%cpu_id .ne. cpu_id) then
!            neigh%var_deallocate_flag = .false.
!            if (.not. neigh%var_allocate_flag) then
!               allocate(neigh%ro(nx_block, ny_block, nz_block), neigh%mx(nx_block, ny_block, nz_block),                            &
!                        neigh%my(nx_block, ny_block, nz_block), neigh%mz(nx_block, ny_block, nz_block),                            &
!                        neigh%bx(nx_block, ny_block, nz_block), neigh%by(nx_block, ny_block, nz_block),                            &
!                        neigh%bz(nx_block, ny_block, nz_block), neigh%en(nx_block, ny_block, nz_block),                            &
!                        neigh%gx(nx_block, ny_block, nz_block), neigh%gy(nx_block, ny_block, nz_block),                            &
!                        neigh%gz(nx_block, ny_block, nz_block), neigh%po(nx_block, ny_block, nz_block))
!               allocate(neigh%fxro_bnd(ny_block, nz_block, n_neighs), neigh%fxmx_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxmy_bnd(ny_block, nz_block, n_neighs), neigh%fxmz_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxbx_bnd(ny_block, nz_block, n_neighs), neigh%fxby_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxbz_bnd(ny_block, nz_block, n_neighs), neigh%fxen_bnd(ny_block, nz_block, n_neighs),                &
!                        neigh%fxpo_bnd(ny_block, nz_block, n_neighs),                                                              &
!                        neigh%fyro_bnd(nx_block, nz_block, n_neighs), neigh%fymx_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fymy_bnd(nx_block, nz_block, n_neighs), neigh%fymz_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fybx_bnd(nx_block, nz_block, n_neighs), neigh%fyby_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fybz_bnd(nx_block, nz_block, n_neighs), neigh%fyen_bnd(nx_block, nz_block, n_neighs),                &
!                        neigh%fypo_bnd(nx_block, nz_block, n_neighs),                                                              &
!                        neigh%fzro_bnd(nx_block, ny_block, n_neighs), neigh%fzmx_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzmy_bnd(nx_block, ny_block, n_neighs), neigh%fzmz_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzbx_bnd(nx_block, ny_block, n_neighs), neigh%fzby_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzbz_bnd(nx_block, ny_block, n_neighs), neigh%fzen_bnd(nx_block, ny_block, n_neighs),                &
!                        neigh%fzpo_bnd(nx_block, ny_block, n_neighs))
!               neigh%var_allocate_flag = .true.
!               if (ini_value_save_flag .ne. 0) then
!                  allocate(neigh%ro0(nx_block, ny_block, nz_block), neigh%mx0(nx_block, ny_block, nz_block),                       &
!                           neigh%my0(nx_block, ny_block, nz_block), neigh%mz0(nx_block, ny_block, nz_block),                       &
!                           neigh%bx0(nx_block, ny_block, nz_block), neigh%by0(nx_block, ny_block, nz_block),                       &
!                           neigh%bz0(nx_block, ny_block, nz_block), neigh%en0(nx_block, ny_block, nz_block))
!               endif
!            endif
            n_neighs_exchange_send_z(neigh_cpu_id_p1) = n_neighs_exchange_send_z(neigh_cpu_id_p1) + 1
            neigh_index = n_neighs_exchange_send_z(neigh_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!           for the case n_neighs_exchange_send_z(neigh_cpu_id_p1) larger than the exchange_size_z
!----------------------------------------------------------------------------------------------------------------------------------|
            if (neigh_index .gt. exchange_size_z) then
               allocate(neighs_exchange_info_send_z_tmp(n_d_l + 1, exchange_size_z, cpu_number))
               allocate(neighs_exchange_info_recv_z_tmp(n_d_l + 1, exchange_size_z, cpu_number))
               exchange_size_z_tmp = exchange_size_z
               neighs_exchange_info_send_z_tmp = neighs_exchange_info_send_z
               neighs_exchange_info_recv_z_tmp = neighs_exchange_info_recv_z
               exchange_size_z = exchange_size_z + ini_block_x * ini_block_y * ini_block_z
               deallocate(neighs_exchange_info_send_z)
               deallocate(neighs_exchange_info_recv_z)
               allocate(neighs_exchange_info_send_z(n_d_l + 1, exchange_size_z, cpu_number))
               allocate(neighs_exchange_info_recv_z(n_d_l + 1, exchange_size_z, cpu_number))
               neighs_exchange_info_send_z(:, 1 : exchange_size_z_tmp, :) = neighs_exchange_info_send_z_tmp
               neighs_exchange_info_recv_z(:, 1 : exchange_size_z_tmp, :) = neighs_exchange_info_recv_z_tmp
               deallocate(neighs_exchange_info_send_z_tmp)
               deallocate(neighs_exchange_info_recv_z_tmp)
            endif
            neighs_exchange_info_send_z(1 : n_d_l, neigh_index, neigh_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
            neighs_exchange_info_send_z(n_d_l + 1, neigh_index, neigh_cpu_id_p1) = k_neigh

!----------------------------------------------------------------------------------------------------------------------------------|
!           collect information of neighbors for fixing boundary data in z because of the shareblocks (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
!            do i_neigh_x = -1, 1, 2
!               neigh_x => current%neigh(i_neigh_x, 0)%pblock
!               if (associated (neigh_x)) then
!                  if (neigh_x%lv .eq. current%lv - 1) then
!                     n_neighs_exchange_send_fix_z(neigh_cpu_id_p1) = n_neighs_exchange_send_fix_z(neigh_cpu_id_p1) + 1
!                     exit
!                  endif
!               endif
!            enddo
         endif

!----------------------------------------------------------------------------------------------------------------------------------|
!        collect information of neighbors for sending sharing block data in z (same levels)
!----------------------------------------------------------------------------------------------------------------------------------|
         if (neigh%lv .eq. current%lv .and. current%nc .ne. 0 .and. neigh%nc .eq. 0) then
            child_send_flag = .false.
            if (k_neigh .eq. -1) k_block = 1
            if (k_neigh .eq. 1) k_block = ratio
            do j_block = 1, ratio
            do i_block = 1, ratio
               child => current%child(i_block, j_block, k_block)%pblock
               child_cpu_id_p1 = child%cpu_id + 1
               if (child%cpu_id .ne. current%cpu_id .and. .not. child_send_flag(child_cpu_id_p1)) then
                  n_neighs_shareblock_send_z(child_cpu_id_p1) = n_neighs_shareblock_send_z(child_cpu_id_p1) + 1
                  neigh_index = n_neighs_shareblock_send_z(child_cpu_id_p1)
!----------------------------------------------------------------------------------------------------------------------------------|
!                 for the case n_neighs_shareblock_send_z(neigh_cpu_id_p1) larger than the shareblock_size_z
!----------------------------------------------------------------------------------------------------------------------------------|
                  if (neigh_index .gt. shareblock_size_z) then
                     allocate(neighs_shareblock_info_send_z_tmp(n_d_l + 1, shareblock_size_z, cpu_number))
                     allocate(neighs_shareblock_info_recv_z_tmp(n_d_l + 1, shareblock_size_z, cpu_number))
                     shareblock_size_z_tmp = shareblock_size_z
                     neighs_shareblock_info_send_z_tmp = neighs_shareblock_info_send_z
                     neighs_shareblock_info_recv_z_tmp = neighs_shareblock_info_recv_z
                     shareblock_size_z = shareblock_size_z + ini_block_x * ini_block_y * ini_block_z
                     deallocate(neighs_shareblock_info_send_z)
                     deallocate(neighs_shareblock_info_recv_z)
                     allocate(neighs_shareblock_info_send_z(n_d_l + 1, shareblock_size_z, cpu_number))
                     allocate(neighs_shareblock_info_recv_z(n_d_l + 1, shareblock_size_z, cpu_number))
                     neighs_shareblock_info_send_z(:, 1 : shareblock_size_z_tmp, :) = neighs_shareblock_info_send_z_tmp
                     neighs_shareblock_info_recv_z(:, 1 : shareblock_size_z_tmp, :) = neighs_shareblock_info_recv_z_tmp
                     deallocate(neighs_shareblock_info_send_z_tmp)
                     deallocate(neighs_shareblock_info_recv_z_tmp)
                  endif
                  neighs_shareblock_info_send_z(1 : n_d_l, neigh_index, child_cpu_id_p1) = reshape(current%id, (/ n_d_l /))
                  neighs_shareblock_info_send_z(n_d_l + 1, neigh_index, child_cpu_id_p1) = k_neigh
                  child_send_flag(child_cpu_id_p1) = .true.
               endif
            enddo
            enddo
         endif
      enddo

      current => current%next
   enddo

!!----------------------------------------------------------------------------------------------------------------------------------|
!!  deallocate the memory which is unnecessary
!!----------------------------------------------------------------------------------------------------------------------------------|
!   current => base%framework_next
!   do while (current%lv .ne. 0)
!      if (current%var_deallocate_flag) then
!         if (current%var_allocate_flag) then
!            deallocate(current%ro, current%mx, current%my, current%mz, current%bx, current%by, current%bz, current%en,             &
!                       current%gx, current%gy, current%gz, current%po)
!            deallocate(current%fxro_bnd, current%fxmx_bnd, current%fxmy_bnd, current%fxmz_bnd,                                     &
!                       current%fxbx_bnd, current%fxby_bnd, current%fxbz_bnd, current%fxen_bnd, current%fxpo_bnd,                   &
!                       current%fyro_bnd, current%fymx_bnd, current%fymy_bnd, current%fymz_bnd,                                     &
!                       current%fybx_bnd, current%fyby_bnd, current%fybz_bnd, current%fyen_bnd, current%fypo_bnd,                   &
!                       current%fzro_bnd, current%fzmx_bnd, current%fzmy_bnd, current%fzmz_bnd,                                     &
!                       current%fzbx_bnd, current%fzby_bnd, current%fzbz_bnd, current%fzen_bnd, current%fzpo_bnd)
!            current%var_allocate_flag = .false.
!            if (ini_value_save_flag .ne. 0) then
!               deallocate(current%ro0, current%mx0, current%my0, current%mz0, current%bx0, current%by0, current%bz0, current%en0)
!            endif
!         endif
!         current%var_deallocate_flag = .false.
!      endif
!      current => current%framework_next
!   enddo

!!----------------------------------------------------------------------------------------------------------------------------------|
!!  test
!!----------------------------------------------------------------------------------------------------------------------------------|
!   n_tmp = 0
!   tmp_flag = 0
!   current => base%framework_next
!   do while (current%lv .ne. 0)
!      if (.not. current%var_allocate_flag) cycle
!      if (current%cpu_id .eq. cpu_id) cycle
!      k_neigh = 0
!      j_neigh = 0
!      do i_neigh = -1, 1, 2
!         neigh => current%neigh(i_neigh, j_neigh, k_neigh)%pblock
!         if (neigh%cpu_id .eq. cpu_id) tmp_flag = 1
!      enddo
!      k_neigh = 0
!      i_neigh = 0
!      do j_neigh = -1, 1, 2
!         neigh => current%neigh(i_neigh, j_neigh, k_neigh)%pblock
!         if (neigh%cpu_id .eq. cpu_id) tmp_flag = 1
!      enddo
!      j_neigh = 0
!      i_neigh = 0
!      do k_neigh = -1, 1, 2
!         neigh => current%neigh(i_neigh, j_neigh, k_neigh)%pblock
!         if (.not. associated(neigh)) cycle
!         if (neigh%cpu_id .eq. cpu_id) tmp_flag = 1
!      enddo
!      if (tmp_flag .eq. 0) then
!         print*, "Error", current%id
!      endif
!      current => current%framework_next
!   enddo

!----------------------------------------------------------------------------------------------------------------------------------|
!  collect the information from other cpu
!----------------------------------------------------------------------------------------------------------------------------------|
   call mpi_allgather(n_neighs_reflux_send_x, cpu_number, mpi_integer4,                                                            &
      n_neighs_reflux_sendrecv_x, cpu_number, mpi_integer4,                                                                        &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_reflux_send_y, cpu_number, mpi_integer4,                                                            &
      n_neighs_reflux_sendrecv_y, cpu_number, mpi_integer4,                                                                        &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_reflux_send_z, cpu_number, mpi_integer4,                                                            &
      n_neighs_reflux_sendrecv_z, cpu_number, mpi_integer4,                                                                        &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_shareblock_send_x, cpu_number, mpi_integer4,                                                        &
      n_neighs_shareblock_sendrecv_x, cpu_number, mpi_integer4,                                                                    &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_shareblock_send_y, cpu_number, mpi_integer4,                                                        &
      n_neighs_shareblock_sendrecv_y, cpu_number, mpi_integer4,                                                                    &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_shareblock_send_z, cpu_number, mpi_integer4,                                                        &
      n_neighs_shareblock_sendrecv_z, cpu_number, mpi_integer4,                                                                    &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_exchange_send_x, cpu_number, mpi_integer4,                                                          &
      n_neighs_exchange_sendrecv_x, cpu_number, mpi_integer4,                                                                      &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_exchange_send_y, cpu_number, mpi_integer4,                                                          &
      n_neighs_exchange_sendrecv_y, cpu_number, mpi_integer4,                                                                      &
      mpi_comm_world, error)
   call mpi_allgather(n_neighs_exchange_send_z, cpu_number, mpi_integer4,                                                          &
      n_neighs_exchange_sendrecv_z, cpu_number, mpi_integer4,                                                                      &
      mpi_comm_world, error)

!----------------------------------------------------------------------------------------------------------------------------------|
!  resize the buffer array for reflux, exchange and shareblock
!----------------------------------------------------------------------------------------------------------------------------------|
   reflux_size_send_x = max(sum(n_neighs_reflux_sendrecv_x(:, cpu_id_p1)), 1)
   reflux_size_recv_x = max(sum(n_neighs_reflux_sendrecv_x(cpu_id_p1, :)), 1)
   reflux_size_send_y = max(sum(n_neighs_reflux_sendrecv_y(:, cpu_id_p1)), 1)
   reflux_size_recv_y = max(sum(n_neighs_reflux_sendrecv_y(cpu_id_p1, :)), 1)
   reflux_size_send_z = max(sum(n_neighs_reflux_sendrecv_z(:, cpu_id_p1)), 1)
   reflux_size_recv_z = max(sum(n_neighs_reflux_sendrecv_z(cpu_id_p1, :)), 1)
   shareblock_size_send_x = max(sum(n_neighs_shareblock_sendrecv_x(:, cpu_id_p1)), 1)
   shareblock_size_recv_x = max(sum(n_neighs_shareblock_sendrecv_x(cpu_id_p1, :)), 1)
   shareblock_size_send_y = max(sum(n_neighs_shareblock_sendrecv_y(:, cpu_id_p1)), 1)
   shareblock_size_recv_y = max(sum(n_neighs_shareblock_sendrecv_y(cpu_id_p1, :)), 1)
   shareblock_size_send_z = max(sum(n_neighs_shareblock_sendrecv_z(:, cpu_id_p1)), 1)
   shareblock_size_recv_z = max(sum(n_neighs_shareblock_sendrecv_z(cpu_id_p1, :)), 1)
   exchange_size_send_x = max(sum(n_neighs_exchange_sendrecv_x(:, cpu_id_p1)), 1)
   exchange_size_recv_x = max(sum(n_neighs_exchange_sendrecv_x(cpu_id_p1, :)), 1)
   exchange_size_send_y = max(sum(n_neighs_exchange_sendrecv_y(:, cpu_id_p1)), 1)
   exchange_size_recv_y = max(sum(n_neighs_exchange_sendrecv_y(cpu_id_p1, :)), 1)
   exchange_size_send_z = max(sum(n_neighs_exchange_sendrecv_z(:, cpu_id_p1)), 1)
   exchange_size_recv_z = max(sum(n_neighs_exchange_sendrecv_z(cpu_id_p1, :)), 1)

   allocate(neighs_reflux_send_x(sys, ny_no_bnd, nz_no_bnd, reflux_size_send_x))
   allocate(neighs_reflux_recv_x(sys, ny_no_bnd, nz_no_bnd, reflux_size_recv_x))
   allocate(neighs_reflux_send_y(sys, nx_no_bnd, nz_no_bnd, reflux_size_send_y))
   allocate(neighs_reflux_recv_y(sys, nx_no_bnd, nz_no_bnd, reflux_size_recv_y))
   allocate(neighs_reflux_send_z(sys, nx_no_bnd, ny_no_bnd, reflux_size_send_z))
   allocate(neighs_reflux_recv_z(sys, nx_no_bnd, ny_no_bnd, reflux_size_recv_z))
   allocate(neighs_exchange_send_x(sysp1, ng, ny_no_bnd, nz_no_bnd, exchange_size_send_x))
   allocate(neighs_exchange_recv_x(sysp1, ng, ny_no_bnd, nz_no_bnd, exchange_size_recv_x))
   allocate(neighs_exchange_send_y(sysp1, nx_block, ng, nz_no_bnd, exchange_size_send_y))
   allocate(neighs_exchange_recv_y(sysp1, nx_block, ng, nz_no_bnd, exchange_size_recv_y))
   allocate(neighs_exchange_send_z(sysp1, nx_block, ny_block, ng, exchange_size_send_z))
   allocate(neighs_exchange_recv_z(sysp1, nx_block, ny_block, ng, exchange_size_recv_z))
   allocate(neighs_shareblock_send_x(sysp1, ng + 1, ny_block, nz_block, shareblock_size_send_x))
   allocate(neighs_shareblock_recv_x(sysp1, ng + 1, ny_block, nz_block, shareblock_size_recv_x))
   allocate(neighs_shareblock_send_y(sysp1, nx_block, ng + 1, nz_block, shareblock_size_send_y))
   allocate(neighs_shareblock_recv_y(sysp1, nx_block, ng + 1, nz_block, shareblock_size_recv_y))
   allocate(neighs_shareblock_send_z(sysp1, nx_block, ny_block, ng + 1, shareblock_size_send_z))
   allocate(neighs_shareblock_recv_z(sysp1, nx_block, ny_block, ng + 1, shareblock_size_recv_z))

   if (max(maxval(n_neighs_reflux_sendrecv_x(cpu_id_p1, :)),                                                                       &
           maxval(n_neighs_reflux_sendrecv_x(:, cpu_id_p1))) .ne. reflux_size_x) then
      allocate(neighs_reflux_info_send_x_tmp(n_d_l + 1, reflux_size_x, cpu_number))
      allocate(neighs_reflux_info_recv_x_tmp(n_d_l + 1, reflux_size_x, cpu_number))
      reflux_size_x_tmp = min(max(maxval(n_neighs_reflux_sendrecv_x(cpu_id_p1, :)),                                                &
                                  maxval(n_neighs_reflux_sendrecv_x(:, cpu_id_p1))) + 1, reflux_size_x)
      reflux_size_x = max(maxval(n_neighs_reflux_sendrecv_x(cpu_id_p1, :)),                                                        &
                          maxval(n_neighs_reflux_sendrecv_x(:, cpu_id_p1))) + 1
      neighs_reflux_info_send_x_tmp = neighs_reflux_info_send_x
      neighs_reflux_info_recv_x_tmp = neighs_reflux_info_recv_x
      deallocate(neighs_reflux_info_send_x)
      deallocate(neighs_reflux_info_recv_x)
      allocate(neighs_reflux_info_send_x(n_d_l + 1, reflux_size_x, cpu_number))
      allocate(neighs_reflux_info_recv_x(n_d_l + 1, reflux_size_x, cpu_number))
      neighs_reflux_info_send_x(:, 1 : reflux_size_x_tmp, :) =                                                                     &
         neighs_reflux_info_send_x_tmp(:, 1 : reflux_size_x_tmp, :)
      neighs_reflux_info_recv_x(:, 1 : reflux_size_x_tmp, :) =                                                                     &
         neighs_reflux_info_recv_x_tmp(:, 1 : reflux_size_x_tmp, :)
      deallocate(neighs_reflux_info_send_x_tmp)
      deallocate(neighs_reflux_info_recv_x_tmp)
   endif

   if (max(maxval(n_neighs_reflux_sendrecv_y(cpu_id_p1, :)),                                                                       &
           maxval(n_neighs_reflux_sendrecv_y(:, cpu_id_p1))) .ne. reflux_size_y) then
      allocate(neighs_reflux_info_send_y_tmp(n_d_l + 1, reflux_size_y, cpu_number))
      allocate(neighs_reflux_info_recv_y_tmp(n_d_l + 1, reflux_size_y, cpu_number))
      reflux_size_y_tmp = min(max(maxval(n_neighs_reflux_sendrecv_y(cpu_id_p1, :)),                                                &
                                  maxval(n_neighs_reflux_sendrecv_y(:, cpu_id_p1))) + 1, reflux_size_y)
      reflux_size_y = max(maxval(n_neighs_reflux_sendrecv_y(cpu_id_p1, :)),                                                        &
                          maxval(n_neighs_reflux_sendrecv_y(:, cpu_id_p1))) + 1
      neighs_reflux_info_send_y_tmp = neighs_reflux_info_send_y
      neighs_reflux_info_recv_y_tmp = neighs_reflux_info_recv_y
      deallocate(neighs_reflux_info_send_y)
      deallocate(neighs_reflux_info_recv_y)
      allocate(neighs_reflux_info_send_y(n_d_l + 1, reflux_size_y, cpu_number))
      allocate(neighs_reflux_info_recv_y(n_d_l + 1, reflux_size_y, cpu_number))
      neighs_reflux_info_send_y(:, 1 : reflux_size_y_tmp, :) =                                                                     &
         neighs_reflux_info_send_y_tmp(:, 1 : reflux_size_y_tmp, :)
      neighs_reflux_info_recv_y(:, 1 : reflux_size_y_tmp, :) =                                                                     &
         neighs_reflux_info_recv_y_tmp(:, 1 : reflux_size_y_tmp, :)
      deallocate(neighs_reflux_info_send_y_tmp)
      deallocate(neighs_reflux_info_recv_y_tmp)
   endif

   if (max(maxval(n_neighs_reflux_sendrecv_z(cpu_id_p1, :)),                                                                       &
           maxval(n_neighs_reflux_sendrecv_z(:, cpu_id_p1))) .ne. reflux_size_z) then
      allocate(neighs_reflux_info_send_z_tmp(n_d_l + 1, reflux_size_z, cpu_number))
      allocate(neighs_reflux_info_recv_z_tmp(n_d_l + 1, reflux_size_z, cpu_number))
      reflux_size_z_tmp = min(max(maxval(n_neighs_reflux_sendrecv_z(cpu_id_p1, :)),                                                &
                                  maxval(n_neighs_reflux_sendrecv_z(:, cpu_id_p1))) + 1, reflux_size_z)
      reflux_size_z = max(maxval(n_neighs_reflux_sendrecv_z(cpu_id_p1, :)),                                                        &
                          maxval(n_neighs_reflux_sendrecv_z(:, cpu_id_p1))) + 1
      neighs_reflux_info_send_z_tmp = neighs_reflux_info_send_z
      neighs_reflux_info_recv_z_tmp = neighs_reflux_info_recv_z
      deallocate(neighs_reflux_info_send_z)
      deallocate(neighs_reflux_info_recv_z)
      allocate(neighs_reflux_info_send_z(n_d_l + 1, reflux_size_z, cpu_number))
      allocate(neighs_reflux_info_recv_z(n_d_l + 1, reflux_size_z, cpu_number))
      neighs_reflux_info_send_z(:, 1 : reflux_size_z_tmp, :) =                                                                     &
         neighs_reflux_info_send_z_tmp(:, 1 : reflux_size_z_tmp, :)
      neighs_reflux_info_recv_z(:, 1 : reflux_size_z_tmp, :) =                                                                     &
         neighs_reflux_info_recv_z_tmp(:, 1 : reflux_size_z_tmp, :)
      deallocate(neighs_reflux_info_send_z_tmp)
      deallocate(neighs_reflux_info_recv_z_tmp)
   endif

   if (max(maxval(n_neighs_exchange_sendrecv_x(cpu_id_p1, :)),                                                                     &
           maxval(n_neighs_exchange_sendrecv_x(:, cpu_id_p1))) .ne. exchange_size_x) then
      allocate(neighs_exchange_info_send_x_tmp(n_d_l + 1, exchange_size_x, cpu_number))
      allocate(neighs_exchange_info_recv_x_tmp(n_d_l + 1, exchange_size_x, cpu_number))
      exchange_size_x_tmp = min(max(maxval(n_neighs_exchange_sendrecv_x(cpu_id_p1, :)),                                            &
                                    maxval(n_neighs_exchange_sendrecv_x(:, cpu_id_p1))) + 1, exchange_size_x)
      exchange_size_x = max(maxval(n_neighs_exchange_sendrecv_x(cpu_id_p1, :)),                                                    &
                            maxval(n_neighs_exchange_sendrecv_x(:, cpu_id_p1))) + 1
      neighs_exchange_info_send_x_tmp = neighs_exchange_info_send_x
      neighs_exchange_info_recv_x_tmp = neighs_exchange_info_recv_x
      deallocate(neighs_exchange_info_send_x)
      deallocate(neighs_exchange_info_recv_x)
      allocate(neighs_exchange_info_send_x(n_d_l + 1, exchange_size_x, cpu_number))
      allocate(neighs_exchange_info_recv_x(n_d_l + 1, exchange_size_x, cpu_number))
      neighs_exchange_info_send_x(:, 1 : exchange_size_x_tmp, :) =                                                                 &
         neighs_exchange_info_send_x_tmp(:, 1 : exchange_size_x_tmp, :)
      neighs_exchange_info_recv_x(:, 1 : exchange_size_x_tmp, :) =                                                                 &
         neighs_exchange_info_recv_x_tmp(:, 1 : exchange_size_x_tmp, :)
      deallocate(neighs_exchange_info_send_x_tmp)
      deallocate(neighs_exchange_info_recv_x_tmp)
   endif

   if (max(maxval(n_neighs_exchange_sendrecv_y(cpu_id_p1, :)),                                                                     &
           maxval(n_neighs_exchange_sendrecv_y(:, cpu_id_p1))) .ne. exchange_size_y) then
      allocate(neighs_exchange_info_send_y_tmp(n_d_l + 1, exchange_size_y, cpu_number))
      allocate(neighs_exchange_info_recv_y_tmp(n_d_l + 1, exchange_size_y, cpu_number))
      exchange_size_y_tmp = min(max(maxval(n_neighs_exchange_sendrecv_y(cpu_id_p1, :)),                                            &
                                    maxval(n_neighs_exchange_sendrecv_y(:, cpu_id_p1))) + 1, exchange_size_y)
      exchange_size_y = max(maxval(n_neighs_exchange_sendrecv_y(cpu_id_p1, :)),                                                    &
                            maxval(n_neighs_exchange_sendrecv_y(:, cpu_id_p1))) + 1
      neighs_exchange_info_send_y_tmp = neighs_exchange_info_send_y
      neighs_exchange_info_recv_y_tmp = neighs_exchange_info_recv_y
      deallocate(neighs_exchange_info_send_y)
      deallocate(neighs_exchange_info_recv_y)
      allocate(neighs_exchange_info_send_y(n_d_l + 1, exchange_size_y, cpu_number))
      allocate(neighs_exchange_info_recv_y(n_d_l + 1, exchange_size_y, cpu_number))
      neighs_exchange_info_send_y(:, 1 : exchange_size_y_tmp, :) =                                                                 &
         neighs_exchange_info_send_y_tmp(:, 1 : exchange_size_y_tmp, :)
      neighs_exchange_info_recv_y(:, 1 : exchange_size_y_tmp, :) =                                                                 &
         neighs_exchange_info_recv_y_tmp(:, 1 : exchange_size_y_tmp, :)
      deallocate(neighs_exchange_info_send_y_tmp)
      deallocate(neighs_exchange_info_recv_y_tmp)
   endif

   if (max(maxval(n_neighs_exchange_sendrecv_z(cpu_id_p1, :)),                                                                     &
           maxval(n_neighs_exchange_sendrecv_z(:, cpu_id_p1))) .ne. exchange_size_z) then
      allocate(neighs_exchange_info_send_z_tmp(n_d_l + 1, exchange_size_z, cpu_number))
      allocate(neighs_exchange_info_recv_z_tmp(n_d_l + 1, exchange_size_z, cpu_number))
      exchange_size_z_tmp = min(max(maxval(n_neighs_exchange_sendrecv_z(cpu_id_p1, :)),                                            &
                                    maxval(n_neighs_exchange_sendrecv_z(:, cpu_id_p1))) + 1, exchange_size_z)
      exchange_size_z = max(maxval(n_neighs_exchange_sendrecv_z(cpu_id_p1, :)),                                                    &
                            maxval(n_neighs_exchange_sendrecv_z(:, cpu_id_p1))) + 1
      neighs_exchange_info_send_z_tmp = neighs_exchange_info_send_z
      neighs_exchange_info_recv_z_tmp = neighs_exchange_info_recv_z
      deallocate(neighs_exchange_info_send_z)
      deallocate(neighs_exchange_info_recv_z)
      allocate(neighs_exchange_info_send_z(n_d_l + 1, exchange_size_z, cpu_number))
      allocate(neighs_exchange_info_recv_z(n_d_l + 1, exchange_size_z, cpu_number))
      neighs_exchange_info_send_z(:, 1 : exchange_size_z_tmp, :) =                                                                 &
         neighs_exchange_info_send_z_tmp(:, 1 : exchange_size_z_tmp, :)
      neighs_exchange_info_recv_z(:, 1 : exchange_size_z_tmp, :) =                                                                 &
         neighs_exchange_info_recv_z_tmp(:, 1 : exchange_size_z_tmp, :)
      deallocate(neighs_exchange_info_send_z_tmp)
      deallocate(neighs_exchange_info_recv_z_tmp)
   endif

   if (max(maxval(n_neighs_shareblock_sendrecv_x(cpu_id_p1, :)),                                                                   &
           maxval(n_neighs_shareblock_sendrecv_x(:, cpu_id_p1))) .ne. shareblock_size_x) then
      allocate(neighs_shareblock_info_send_x_tmp(n_d_l + 1, shareblock_size_x, cpu_number))
      allocate(neighs_shareblock_info_recv_x_tmp(n_d_l + 1, shareblock_size_x, cpu_number))
      shareblock_size_x_tmp = min(max(maxval(n_neighs_shareblock_sendrecv_x(cpu_id_p1, :)),                                        &
                                      maxval(n_neighs_shareblock_sendrecv_x(:, cpu_id_p1))) + 1, shareblock_size_x)
      shareblock_size_x = max(maxval(n_neighs_shareblock_sendrecv_x(cpu_id_p1, :)),                                                &
                              maxval(n_neighs_shareblock_sendrecv_x(:, cpu_id_p1))) + 1
      neighs_shareblock_info_send_x_tmp = neighs_shareblock_info_send_x
      neighs_shareblock_info_recv_x_tmp = neighs_shareblock_info_recv_x
      deallocate(neighs_shareblock_info_send_x)
      deallocate(neighs_shareblock_info_recv_x)
      allocate(neighs_shareblock_info_send_x(n_d_l + 1, shareblock_size_x, cpu_number))
      allocate(neighs_shareblock_info_recv_x(n_d_l + 1, shareblock_size_x, cpu_number))
      neighs_shareblock_info_send_x(:, 1 : shareblock_size_x_tmp, :) =                                                             &
         neighs_shareblock_info_send_x_tmp(:, 1 : shareblock_size_x_tmp, :)
      neighs_shareblock_info_recv_x(:, 1 : shareblock_size_x_tmp, :) =                                                             &
         neighs_shareblock_info_recv_x_tmp(:, 1 : shareblock_size_x_tmp, :)
      deallocate(neighs_shareblock_info_send_x_tmp)
      deallocate(neighs_shareblock_info_recv_x_tmp)
   endif

   if (max(maxval(n_neighs_shareblock_sendrecv_y(cpu_id_p1, :)),                                                                   &
           maxval(n_neighs_shareblock_sendrecv_y(:, cpu_id_p1))) .ne. shareblock_size_y) then
      allocate(neighs_shareblock_info_send_y_tmp(n_d_l + 1, shareblock_size_y, cpu_number))
      allocate(neighs_shareblock_info_recv_y_tmp(n_d_l + 1, shareblock_size_y, cpu_number))
      shareblock_size_y_tmp = min(max(maxval(n_neighs_shareblock_sendrecv_y(cpu_id_p1, :)),                                        &
                                      maxval(n_neighs_shareblock_sendrecv_y(:, cpu_id_p1))) + 1, shareblock_size_y)
      shareblock_size_y = max(maxval(n_neighs_shareblock_sendrecv_y(cpu_id_p1, :)),                                                &
                              maxval(n_neighs_shareblock_sendrecv_y(:, cpu_id_p1))) + 1
      neighs_shareblock_info_send_y_tmp = neighs_shareblock_info_send_y
      neighs_shareblock_info_recv_y_tmp = neighs_shareblock_info_recv_y
      deallocate(neighs_shareblock_info_send_y)
      deallocate(neighs_shareblock_info_recv_y)
      allocate(neighs_shareblock_info_send_y(n_d_l + 1, shareblock_size_y, cpu_number))
      allocate(neighs_shareblock_info_recv_y(n_d_l + 1, shareblock_size_y, cpu_number))
      neighs_shareblock_info_send_y(:, 1 : shareblock_size_y_tmp, :) =                                                             &
         neighs_shareblock_info_send_y_tmp(:, 1 : shareblock_size_y_tmp, :)
      neighs_shareblock_info_recv_y(:, 1 : shareblock_size_y_tmp, :) =                                                             &
         neighs_shareblock_info_recv_y_tmp(:, 1 : shareblock_size_y_tmp, :)
      deallocate(neighs_shareblock_info_send_y_tmp)
      deallocate(neighs_shareblock_info_recv_y_tmp)
   endif

   if (max(maxval(n_neighs_shareblock_sendrecv_z(cpu_id_p1, :)),                                                                   &
           maxval(n_neighs_shareblock_sendrecv_z(:, cpu_id_p1))) .ne. shareblock_size_z) then
      allocate(neighs_shareblock_info_send_z_tmp(n_d_l + 1, shareblock_size_z, cpu_number))
      allocate(neighs_shareblock_info_recv_z_tmp(n_d_l + 1, shareblock_size_z, cpu_number))
      shareblock_size_z_tmp = min(max(maxval(n_neighs_shareblock_sendrecv_z(cpu_id_p1, :)),                                        &
                                      maxval(n_neighs_shareblock_sendrecv_z(:, cpu_id_p1))) + 1, shareblock_size_z)
      shareblock_size_z = max(maxval(n_neighs_shareblock_sendrecv_z(cpu_id_p1, :)),                                                &
                              maxval(n_neighs_shareblock_sendrecv_z(:, cpu_id_p1))) + 1
      neighs_shareblock_info_send_z_tmp = neighs_shareblock_info_send_z
      neighs_shareblock_info_recv_z_tmp = neighs_shareblock_info_recv_z
      deallocate(neighs_shareblock_info_send_z)
      deallocate(neighs_shareblock_info_recv_z)
      allocate(neighs_shareblock_info_send_z(n_d_l + 1, shareblock_size_z, cpu_number))
      allocate(neighs_shareblock_info_recv_z(n_d_l + 1, shareblock_size_z, cpu_number))
!      allocate(neighs_shareblock_recv_z(sysp1, nx_block, ny_block, ng + 1, shareblock_size_z, cpu_number_neigh))
      neighs_shareblock_info_send_z(:, 1 : shareblock_size_z_tmp, :) =                                                             &
         neighs_shareblock_info_send_z_tmp(:, 1 : shareblock_size_z_tmp, :)
      neighs_shareblock_info_recv_z(:, 1 : shareblock_size_z_tmp, :) =                                                             &
         neighs_shareblock_info_recv_z_tmp(:, 1 : shareblock_size_z_tmp, :)
      deallocate(neighs_shareblock_info_send_z_tmp)
      deallocate(neighs_shareblock_info_recv_z_tmp)
   endif

!----------------------------------------------------------------------------------------------------------------------------------|
   return
end subroutine neigh_statistics
